#pragma once
#include <core/Utility.h>
#include <qbprotocol/include/SSQBModel.h>

#include "../bondlib.h"

class S_BONDLIB_EXPORT CDealDisChartUnit {
 public:
  int m_remainDays;  // 剩余期限
  float m_cdcGov;    //
  float m_cdcCdb;
  float m_dealCdb;
  float m_dealNCdb;
  float m_dealGov;
  float m_dealLocal;
  char m_termRemain[64];  // 期限
  char m_shortName[128];  // 债券简称
  char m_updateTime[64];  // 更新时间，显示提示时格式化
  time_t m_dealTime;
  int m_nId;
  int m_nBondId;
  CDealDisChartUnit() {
    m_remainDays = 0;
    m_cdcGov = 1e-18f;
    m_cdcCdb = 1e-18f;
    m_dealCdb = 1e-18f;
    m_dealNCdb = 1e-18f;
    m_dealGov = 1e-18f;
    m_dealLocal = 1e-18f;
    _InitializeString(m_shortName);
    _InitializeString(m_updateTime);
    m_dealTime = 0;
    m_nId = 0;
  }
  CDealDisChartUnit& operator=(const CDealDisChartUnit& unit) {
    m_remainDays = unit.m_remainDays;
    m_cdcGov = unit.m_cdcGov;
    m_cdcCdb = unit.m_cdcCdb;
    m_dealCdb = unit.m_dealCdb;
    m_dealNCdb = unit.m_dealNCdb;
    m_dealGov = unit.m_dealGov;
    m_dealLocal = unit.m_dealLocal;
    FIELDCOPY(m_shortName, unit.m_shortName);
    FIELDCOPY(m_updateTime, unit.m_updateTime);
    m_dealTime = unit.m_dealTime;
    m_nId = unit.m_nId;
    m_nBondId = unit.m_nBondId;
    return *this;
  }
};
class S_BONDLIB_EXPORT CDealDisChartList {
 public:
  std::list<CDealDisChartUnit> m_List;
};

class S_BONDLIB_EXPORT CComCdcUnit {
 public:
  char m_Period[8];  // 期限
  float m_cdcGov;    // 国债收益率
  float m_cdcCdb;    // 国开债收益率
  CComCdcUnit() {
    _InitializeString(m_Period);
    m_cdcGov = 1e-18f;
    m_cdcCdb = 1e-18f;
  }
};

class S_BONDLIB_EXPORT CComCdcList {
 public:
  std::list<CComCdcUnit> m_List;
};

struct sPanoramicBondDealUnit {
  int m_indexID;
  time_t m_updateTime;
  char m_bondCode[12];     // 债券代码
  char m_bondkey[32 + 1];  // key
  char m_listedmarket[8];  // 市场代码
  char m_price[12];        // 收益率
  char m_cleanPrice[12];   // 成交对应的净价，服务端计算好
  char m_yield[12];        // 成交对应的收益率，服务端计算好
  char m_id[32 + 1];       // 唯一编号
  char m_dealStatus[2];    //"0 ~ 3: 客户端显示成交，
  char m_preCloseYield[12];  // 昨收收益率，服务端做好往前顺延的判断
  char m_preClosecleanPrice[12];  // 昨收净价，服务端做好往前顺延的判断
  char m_withinPeriodDeal
      [2];  // 是否属于20个工作日内有成交的券，'Y'为'是，''或者'N'为'否'；不足20个工作日的券不算入其中
  char m_listedFirstDeal
      [2];  // 是否属于上市后有成交的券，'Y'为'是，''或者'N'为'否'
  char m_quotetype[4];  // 报价类型，0-有意向；1-净价；2-全价；3-收益率；4-利差
  char m_exercise[2];         // 行权到期  (0-行权 1-到期)
  double m_cdcGapPercent;     // 偏离幅度
  double m_cdcGapCleanPrice;  // 净价偏离
  double m_cdcGapBP;          // 偏离BP
  double m_closeGapPercent;   // 涨跌幅度
  double m_closeGapBP;        // 涨跌BP
  int m_messBegin;            // 是否属于聚合的头部，0为是
  int m_Redemption_No;   // 还本方式,是否属于提前还本付息的券j
  char m_OptionType[8];  // 含权类型
  char m_operate[5];     // '消息子类' 成交方向
  char m_companyId[4];   // 经纪公司ID',
  char m_preAdv[12];     // 昨日平均

  // 历史显示额外增加字段，不计入统计
  char m_liquidLevel[4];  // 流动性，ABCD，
  char m_liquid[16];      // 流动性，百分比
  int m_nCdcType;         // 中债估值类型
  char m_cdcYield[25];    // 中债估值组合
  char m_cdcClean[25];    // 中债估值净价组合
  bool IsCleanPrice() const { return strcmp(m_quotetype, "1") == 0; }  // 净价
  bool IsFullPrice() const { return strcmp(m_quotetype, "2") == 0; }   // 全价

  sPanoramicBondDealUnit() {
    m_indexID = 0;
    m_updateTime = 0;
    _InitializeString(m_bondCode);
    _InitializeString(m_bondkey);
    _InitializeString(m_listedmarket);
    _InitializeString(m_price);
    _InitializeString(m_cleanPrice);
    _InitializeString(m_yield);
    _InitializeString(m_id);
    _InitializeString(m_dealStatus);
    _InitializeString(m_preCloseYield);
    _InitializeString(m_preClosecleanPrice);
    _InitializeString(m_withinPeriodDeal);
    _InitializeString(m_listedFirstDeal);
    _InitializeString(m_quotetype);
    _InitializeString(m_exercise);
    _InitializeString(m_OptionType);
    _InitializeString(m_operate);
    _InitializeString(m_companyId);
    _InitializeString(m_preAdv);
    _InitializeString(m_liquidLevel);
    _InitializeString(m_liquid);
    _InitializeString(m_cdcYield);
    _InitializeString(m_cdcClean);
    m_cdcGapPercent = 1e-18f;
    m_cdcGapCleanPrice = -1e7;
    m_cdcGapBP = 1e-18f;
    m_closeGapPercent = 1e-18f;
    m_closeGapBP = 1e-18f;
    m_messBegin = 0;
    m_Redemption_No = 0;
    m_nCdcType = 2;
  }
  sPanoramicBondDealUnit& operator=(const xQBPanoramicMarketStreamUnit& unit) {
    m_indexID = unit.m_indexID;
    m_updateTime = unit.m_updateTime;
    FIELDCOPY(m_bondCode, unit.m_bondCode);
    FIELDCOPY(m_bondkey, unit.m_bondkey);
    FIELDCOPY(m_listedmarket, unit.m_listedmarket);
    FIELDCOPY(m_price, unit.m_price);
    FIELDCOPY(m_cleanPrice, unit.m_cleanPrice);
    FIELDCOPY(m_yield, unit.m_yield);
    FIELDCOPY(m_id, unit.m_id);
    FIELDCOPY(m_dealStatus, unit.m_dealStatus);
    FIELDCOPY(m_preCloseYield, unit.m_preCloseYield);
    FIELDCOPY(m_preClosecleanPrice, unit.m_preClosecleanPrice);
    FIELDCOPY(m_withinPeriodDeal, unit.m_withinPeriodDeal);
    FIELDCOPY(m_listedFirstDeal, unit.m_listedFirstDeal);
    FIELDCOPY(m_quotetype, unit.m_quotetype);
    FIELDCOPY(m_exercise, unit.m_exercise);
    FIELDCOPY(m_operate, unit.m_operate);
    FIELDCOPY(m_companyId, unit.m_companyId);
    FIELDCOPY(m_preAdv, unit.m_preAdv);
    m_cdcGapPercent = 1e-18f;
    m_cdcGapCleanPrice = -1e7;
    m_cdcGapBP = 1e-18f;
    m_closeGapPercent = 1e-18f;
    m_closeGapBP = 1e-18f;
    m_messBegin = 0;
    m_Redemption_No = unit.m_Redemption_No;
    return *this;
  }
  sPanoramicBondDealUnit& operator=(const xQBHisMarketstreamDealUnit_c& unit) {
    m_updateTime = unit.m_dealTime;
    FIELDCOPY(m_bondkey, unit.m_bondkey);
    FIELDCOPY(m_listedmarket, unit.m_listedmarket);
    unit.m_price != 1e-18f ? FMTBUF(m_price, "%0.4f", unit.m_price) : false;
    unit.m_cleanPrice != 1e-18f
        ? FMTBUF(m_cleanPrice, "%0.4f", unit.m_cleanPrice)
        : false;
    unit.m_yield != 1e-18f ? FMTBUF(m_yield, "%0.4f", unit.m_yield) : false;
    // FIELDCOPY(m_id, unit.m_id);
    FIELDCOPY(m_dealStatus, unit.m_dealStatus);
    FIELDCOPY(m_quotetype, unit.m_quotetype);
    FIELDCOPY(m_exercise, unit.m_exercise);
    FMTBUF(m_operate, "%d", unit.m_type);
    FIELDCOPY(m_companyId, unit.m_BrokerID);
    m_cdcGapPercent = 1e-18f;
    m_cdcGapCleanPrice = -1e7;
    m_cdcGapBP = 1e-18f;
    m_closeGapPercent = 1e-18f;
    m_closeGapBP = 1e-18f;
    // m_messBegin = 0; //不修改messBegin
    return *this;
  }
  sPanoramicBondDealUnit& operator=(const sPanoramicBondDealUnit& unit) {
    m_indexID = unit.m_indexID;
    m_updateTime = unit.m_updateTime;
    FIELDCOPY(m_bondCode, unit.m_bondCode);
    FIELDCOPY(m_bondkey, unit.m_bondkey);
    FIELDCOPY(m_listedmarket, unit.m_listedmarket);
    FIELDCOPY(m_price, unit.m_price);
    FIELDCOPY(m_cleanPrice, unit.m_cleanPrice);
    FIELDCOPY(m_yield, unit.m_yield);
    FIELDCOPY(m_id, unit.m_id);
    FIELDCOPY(m_dealStatus, unit.m_dealStatus);
    FIELDCOPY(m_preCloseYield, unit.m_preCloseYield);
    FIELDCOPY(m_preClosecleanPrice, unit.m_preClosecleanPrice);
    FIELDCOPY(m_withinPeriodDeal, unit.m_withinPeriodDeal);
    FIELDCOPY(m_quotetype, unit.m_quotetype);
    FIELDCOPY(m_exercise, unit.m_exercise);
    FIELDCOPY(m_OptionType, unit.m_OptionType);
    FIELDCOPY(m_operate, unit.m_operate);
    FIELDCOPY(m_companyId, unit.m_companyId);
    FIELDCOPY(m_preAdv, unit.m_preAdv);
    FIELDCOPY(m_liquidLevel, unit.m_liquidLevel);
    FIELDCOPY(m_liquid, unit.m_liquid);
    FIELDCOPY(m_cdcYield, unit.m_cdcYield);
    FIELDCOPY(m_cdcClean, unit.m_cdcClean);
    m_cdcGapPercent = unit.m_cdcGapPercent;
    m_cdcGapCleanPrice = unit.m_cdcGapCleanPrice;
    m_cdcGapBP = unit.m_cdcGapBP;
    m_closeGapPercent = unit.m_closeGapPercent;
    m_closeGapBP = unit.m_closeGapBP;
    m_messBegin = unit.m_messBegin;
    m_Redemption_No = unit.m_Redemption_No;
    m_nCdcType = unit.m_nCdcType;
    return *this;
  }

  bool operator<(const sPanoramicBondDealUnit& obj) const {
    time_t t1 = m_updateTime;
    time_t t2 = obj.m_updateTime;
    return t1 == t2 ? (m_indexID > obj.m_indexID) : (t1 > t2);
  }
  bool operator==(const sPanoramicBondDealUnit& obj) const {
    return strcmp(m_id, obj.m_id) == 0;
  }
};

class S_BONDLIB_EXPORT CPanoramicBondDealList {
 public:
  std::list<sPanoramicBondDealUnit> m_List;
};

//////////////////////////////////////////////////////////
// BondDealInfo
// 存放单券成交-统计数据，笔数，最后更新时间，成交列表（按最后更新排序）
//////////////////////////////////////////////////////////
class S_BONDLIB_EXPORT BondDealInfo {
 public:
  BondDealInfo();
  BondDealInfo(const BondDealInfo& one);
  void insert(sPanoramicBondDealUnit& unit);
  void rebuildList();
  void sort();

 public:
  int m_count;
  time_t m_lastUpdate;
  double m_cdcValue;
  char m_lastClose[12];
  bool m_bytm;  // 到期成交收益率
  std::vector<sPanoramicBondDealUnit> m_tradeList;
};

typedef std::map<int, BondDealInfo> MapDealInfo;  //<bondIndex, BondDealInfo>
class S_BONDLIB_EXPORT CPanoramicBondDealMap {
 public:
  CPanoramicBondDealMap();
  bool isEmpty();
  void clear();
  int getDealCount(const int bondIndex);
  time_t getLastUpdate(const int bondIndex);
  const BondDealInfo& getDealInfo(const int bondIndex);
  MapDealInfo& getBondDeal(int type);

 private:
  std::map<int, MapDealInfo>
      m_mapBondDeal;  // 对应的成交，用利率债/信用债/NCD类型区分
  // 	MapDealInfo m_mapInterestDeal; // <bondIndex, BondDealInfo>
  // 	MapDealInfo m_mapCreditDeal; // <bondIndex, BondDealInfo>
  // 	MapDealInfo m_mapNCDDeal; // <bondIndex, BondDealInfo>
};

class S_BONDLIB_EXPORT CChangeDistributionData {
 public:
  std::map<int, CPanoramicBondDealList> m_mpData;
};

namespace panoramic {
enum kDataType { kCdcPercent = 0, kCdcBP, kClosePercent, kCloseBP, kTypeMax };

enum kBondType {
  bondType_null = -1,
  bondType_interest,
  bondType_credit,
  bondType_ncd,
  bondType_ncdPrimary
};
}  // namespace panoramic

// added by shiy20210629
namespace ratebondpanoramic {
enum kweek { Type_null = -1, Type_laskweek, Type_thisweek, Type_nextweek };
}

class S_BONDLIB_EXPORT CRateBondUnit {
 public:
  char m_changeName[14];  // 债券类型名称
  float m_lastweekCount;  // 上周发行量
  float m_thisweekCount;  // 本周发行量
  float m_nextweekCount;  // 下周发行量

  float m_countArray[3];  // 0:上周发行量;1:本周发行量;2:下周发行量
  int m_nIndex;           // 特殊index标志
  CRateBondUnit() {
    _InitializeString(m_changeName);
    m_lastweekCount = 1e-18f;
    m_thisweekCount = 1e-18f;
    m_nextweekCount = 1e-18f;

    m_countArray[0] = 1e-18f;
    m_countArray[1] = 1e-18f;
    m_countArray[2] = 1e-18f;

    m_nIndex = 0;
  }
};

class S_BONDLIB_EXPORT CRateBondMap {
 public:
  std::map<int, CRateBondUnit> m_Map;  // 债券类型，债券详细展示
};

class S_BONDLIB_EXPORT CRateBondList {
 public:
  CRateBondList() {}
  virtual ~CRateBondList() {}
  std::list<int> m_List;  // 债券索引
};